package com.zhuiyun.project.api.personmessage.service.impl;

import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.zhuiyun.project.api.message.entity.Message;
import com.zhuiyun.project.api.message.service.MessageService;
import com.zhuiyun.project.api.message.config.MessageType;
import com.zhuiyun.project.api.messagelist.service.MessageListService;
import com.zhuiyun.project.api.personmessage.entity.PersonMessage;
import com.zhuiyun.project.api.personmessage.mapper.PersonMessageMapper;
import com.zhuiyun.project.api.personmessage.model.PersonMessageModel;
import com.zhuiyun.project.api.personmessage.service.PersonMessageService;
import com.zhuiyun.project.common.response.CommonResult;
import com.zhuiyun.project.util.BeanUtils;
import com.zhuiyun.project.websocket.SocketServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ClassName PersonServiceImpl
 * @Description TODO
 * @Author kdj
 * @Date 2023/6/27 14:29
 **/
@Service
public class PersonMessageServiceImpl implements PersonMessageService {

    @Autowired
    private MessageService messageService;
    @Autowired
    private PersonMessageMapper personMessageMapper;

    @Autowired
    private MessageListService messageListService;
    @Autowired
    private SocketServer socketServer;

    /**
     * @param personMessageModel
     * @Author kdj
     * @Description 撤回消息
     * @Date 2023/7/18 15:24
     * @Return int
     */
    @Override
    public int recallMsg(PersonMessageModel personMessageModel) {
        //根据uuid找到该消息
        String uuid = personMessageModel.getUuid();
        PersonMessage msgByUuid = personMessageMapper.getMsgByUuid(uuid);
        //修改该对象的撤回标识为1
        msgByUuid.setIsWithdraw(1);
        personMessageMapper.updateByPrimaryKeySelective(msgByUuid);
        //修改messageList的未读数
        messageListService.upMsgListUmReadZero(personMessageModel.getFromId(), personMessageModel.getToId(), MessageType.PerMsgType, 1, false);
        //判断是不是最后一个数据
        if (msgByUuid.getIsLast() == 1) {
            //修改
            messageListService.updateChatList(msgByUuid.getMessageId());
        }
        return msgByUuid.getId();
    }

    /**
     * @param personMessageModel
     * @Author kdj
     * @Description 添加聊天记录
     * @Date 2023/6/27 14:37
     * @Return int
     */
    @Override
    @Transactional
    public int insertPerMsg(PersonMessageModel personMessageModel) {
        //判断对象是否为空
        if (ObjectUtil.isNotEmpty(personMessageModel)) {
            PersonMessage personMessage = new PersonMessage();
            BeanUtils.copy(personMessageModel, personMessage);
            //将此二人以往的最后聊天消息，置为不是最后的消息
            /* UPDATE [PersonMessage]
            SET [isLast] = 0
            WHERE [isLast] = 1
            AND [delFlag] = 0
            AND (
                    ([toId] = 'toId值' AND [fromId] = 'fromId值')
            OR ([toId] = 'fromId值' AND [fromId] = 'toId值')
            )*/
            Example updateBefore = new Example(PersonMessage.class);
            updateBefore.createCriteria().andEqualTo("isLast", 1)
                    .andEqualTo("delFlag", 0);
            Example.Criteria orOne = updateBefore.createCriteria().andEqualTo("toId", personMessage.getToId())
                    .andEqualTo("fromId", personMessage.getFromId());
            updateBefore.and(orOne);
            Example.Criteria orTwo = updateBefore.createCriteria().andEqualTo("toId", personMessage.getFromId())
                    .andEqualTo("fromId", personMessage.getToId());
            updateBefore.or(orTwo);
            PersonMessage personMessage1 = new PersonMessage();
            personMessage1.setIsLast(0);
            //修改 最后一条的isLast为0
            personMessageMapper.updateByExampleSelective(personMessage1, updateBefore);
            //添加到message表中  类型：单聊
            int messageId = messageService.insertMsg(new Message(personMessageModel.getUuid(), 1));
            personMessage.setMessageId(messageId);
            //默认 数据
            personMessage.setDelFlag(0);
            personMessage.setIsRead(0);
            personMessage.setIsWithdraw(0);
            //最后聊天信息
            personMessage.setIsLast(1);
            personMessage.setCreateTime(new Date());
            personMessage.setUpdateTime(new Date());
            personMessageMapper.insertSelective(personMessage);
            //增加或者修改messageList
            messageListService.updateChatList(messageId);
            return personMessage.getId();
        }
        return 0;
    }

    /**
     * @param fromId
     * @param toId
     * @Author kdj
     * @Description 获取单聊的聊天记录
     * @Date 2023/6/27 19:10
     * @Return com.zhuiyun.project.common.response.CommonResult
     */
    @Override
    public CommonResult getChatRecord(int fromId, int toId) {
        //查询单聊的聊天记录
        List<PersonMessageModel> personMessages = personMessageMapper.getChatRecord(fromId, toId);
        //使用stream得到map
        //map结构：toId，fromId,createTime,content,msgType
        List<Map> mapList = personMessages.stream().filter(personMessageModel -> {
            String deleteUserId = personMessageModel.getDeleteUserId();
            if (deleteUserId != null && deleteUserId.contains(",")) {
                String[] split = deleteUserId.split(",");
                if (split.length == 0) {
                    return true;
                }
                for (String s : split) {
                    int id = Integer.parseInt(s);
                    if (id == fromId) {
                        return false;
                    }
                }
            }
            return true;
        }).map(personMessage -> {
            return getMap(personMessage);
        }).collect(Collectors.toList());

        return CommonResult.ok(mapList);
    }

    /**
     * @param personMessage
     * @Author kdj
     * @Description 将perMsg格式转为单聊websocket中的格式
     * @Date 2023/7/21 18:20
     * @Return java.util.Map
     */
    private static Map getMap(PersonMessageModel personMessage) {
        Map map = new HashMap<>();
        map.put("toId", personMessage.getToId());
        map.put("fromId", personMessage.getFromId());
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String time = simpleDateFormat.format(personMessage.getCreateTime());
        map.put("createTime", time);
        map.put("content", personMessage.getContent());
        map.put("chatType", MessageType.PerMsgType);
        map.put("uuid", personMessage.getUuid());
        map.put("isWithdraw", personMessage.getIsWithdraw() == 0 ? false : true);
        map.put("isRead", personMessage.getIsRead() == 0 ? false : true);
        String msgType = null;
        switch (personMessage.getMsgType()) {
            case 0:
                msgType = "text";
                break;
            case 1:
                msgType = "image";
                break;
            case 2:
                msgType = "video";
                break;
            case 3:
                msgType = "other";
                break;
                //链接类型
            case 4:
                msgType = "link";
                break;
        }
        map.put("msgType", msgType);
        return map;
    }

    /**
     * @param fromId
     * @param toId   一般是 当前登录者
     * @Author kdj
     * @Description 清空未读信息
     * @Date 2023/6/28 15:40
     * @Return com.zhuiyun.project.common.response.CommonResult
     */
    @Override
    @Transactional
    public CommonResult cleanUnReadMsg(int fromId, int toId) {
        //将personMessage对象的未读改为已读
        //修改的是好友发送的  我接受的
        //条件
        Example example = new Example(PersonMessage.class);
        example.createCriteria().andEqualTo("fromId", fromId)
                .andEqualTo("toId", toId).andEqualTo("isRead", 0);
        PersonMessage personMessage = new PersonMessage();
        //已读
        personMessage.setIsRead(1);
        //修改时间
        personMessage.setUpdateTime(new Date());
        //修改
        personMessageMapper.updateByExampleSelective(personMessage, example);
        //修改聊天列表的未读数量
        messageListService.upMsgListUmReadZero(fromId, toId, MessageType.PerMsgType, 0, false);
        return CommonResult.ok();
    }

    /**
     * @param fromId
     * @param toId
     * @Author kdj
     * @Description 发送添加成功后的第一条消息
     * @Date 2023/6/29 9:09
     * @Return boolean
     */
    @Override
    public boolean sendFirstMsg(int fromId, int toId) {
        //设置第一条聊天信息的内容
        PersonMessage personMessage = new PersonMessage();
        personMessage.setMsgType(0);
        personMessage.setContent("你好，我们可以聊天了！");
        personMessage.setToId(toId);
        personMessage.setFromId(fromId);
        personMessage.setIsWithdraw(0);
        personMessage.setIsRead(0);
        personMessage.setMsgType(0);
        personMessage.setCreateTime(new Date());
        //创建model
        PersonMessageModel personMessageModel = new PersonMessageModel();
        //根据uuid生成唯一id
        UUID uuid = UUID.randomUUID();
        String s = fromId + uuid.toString() + "hello";
        BeanUtils.copy(personMessage, personMessageModel);
        personMessageModel.setUuid(s);
        boolean b = this.insertPerMsg(personMessageModel) > 0 ? true : false;
        if (b) {
            //向websocket发消息
            Map map = getMap(personMessageModel);
            map.put("type", "person_message");
            socketServer.sendMessageById(MessageType.socketApp + "_" + toId, JSONUtil.toJsonStr(map));
            socketServer.sendMessageById(MessageType.socketApp + "_" + fromId, JSONUtil.toJsonStr(map));
        }
        //添加信息
        return b;
    }

    /**
     * @param fromId
     * @param toId
     * @Author kdj
     * @Description 获取聊天记录的最后一条记录
     * @Date 2023/7/19 9:49
     * @Return com.zhuiyun.project.api.personmessage.entity.PersonMessage
     */
    @Override
    public PersonMessage getMsgIsLast(int fromId, int toId) {
        Example example = new Example(PersonMessage.class);
        example.createCriteria().andEqualTo("toId", toId)
                .andEqualTo("fromId", fromId);
        Example.Criteria orTwo = example.createCriteria().andEqualTo("toId", fromId)
                .andEqualTo("fromId", toId);
        example.or(orTwo);
        example.and(example.createCriteria()
                .andEqualTo("delFlag", 0)
                .andEqualTo("isLast", 1));
        List<PersonMessage> personMessages = personMessageMapper.selectByExample(example);
        //判断personMessages有条数据
        if (personMessages.size() == 1) {
            //只有一条，isLast的内容
            return personMessages.get(0);
        } else {
            //证明有人删除过
            //遍历列表  获取delUserId中有没该id的聊天消息
            for (PersonMessage personMessage : personMessages) {
                if (personMessage.getDeleteUserId().contains("\"" + fromId + "\",")) {
                    //如果包含的话 直接返回
                    return personMessage;
                }
            }
        }
        return null;
    }

    /**
     * @param personMessage
     * @param fromId
     * @Author kdj
     * @Description 删除消息
     * @Date 2023/7/20 15:00
     * @Return void
     */
    @Override
    public int upDelMsg(PersonMessage personMessage, int fromId) {
        //判断该消息是否被删除过
        String deleteUserId = personMessage.getDeleteUserId();
        if (deleteUserId != null && deleteUserId.contains(",")) {
            String[] split = deleteUserId.split(",");
            if (split.length == 0) {
                return 0;
            }
            for (String s : split) {
                int id = Integer.parseInt(s);
                if (id == fromId) {
                    return 0;
                }
            }
        }
        deleteUserId = deleteUserId != null ? deleteUserId : "";
        //修改
        // 将 fromId 转换为字符串，并添加到 deleteUserId 后面
        String updatedDeleteUserId = deleteUserId + fromId + ",";

        // 修改
        personMessage.setDeleteUserId(updatedDeleteUserId);
        return personMessageMapper.upDelMsg(personMessage.getDeleteUserId(), personMessage.getId());
    }

    /**
     * @param fromId
     * @param toId
     * @Author kdj
     * @Description 获取单聊聊天内容中最后一条消息（删除之后）
     * @Date 2023/7/31 11:22
     * @Return com.zhuiyun.project.api.personmessage.entity.PersonMessage
     */
    @Override
    public PersonMessage getMsgLastInfo(int fromId, int toId,int userId) {
        int open = 1;
        int size = 10;
        PersonMessageModel personMessageModel1 = getPersonMessageModel(fromId, toId, open, size,userId);
        if (personMessageModel1==null){
            return null;
        }
        PersonMessage personMessage = new PersonMessage();
        BeanUtils.copy(personMessageModel1, personMessage);
        return personMessage;
    }

    /**
     * @param fromId
     * @param toId
     * @param open
     * @param size
     * @Author kdj
     * @Description 获取最后一个消息
     * @Date 2023/7/31 11:46
     * @Return com.zhuiyun.project.api.personmessage.model.PersonMessageModel
     */
    private PersonMessageModel getPersonMessageModel(int fromId, int toId, int open, int size,int userId) {
        //查询单聊的聊天记录
        List<PersonMessageModel> personMessages = personMessageMapper.getChatRecordLimit(fromId, toId, open, size);

        //使用stream得到最后一个没被删除的消息
        PersonMessageModel personMessageModel1 = null;
        for (PersonMessageModel personMessage : personMessages) {
            String deleteUserId = personMessage.getDeleteUserId();
            if (deleteUserId == null) {
                // 取出该值
                personMessageModel1 = personMessage;
                break;
            } else if (deleteUserId != null && deleteUserId.contains(",")) {
                String[] split = deleteUserId.split(",");
                for (String s : split) {
                    int id = Integer.parseInt(s);
                    if (id != userId) {
                        personMessageModel1 = personMessage; break;
                    }
                }
            }
        }
        //判断personMessages的数量》10  就继续递归 并且
        //判断personMessageModel1还是不是null如果是的话open继续
        // 判断递归终止条件：如果消息数量小于等于10或找到了未删除的消息，则不再递归
        if (personMessages.size() <= 10 || personMessageModel1 != null) {
            return personMessageModel1;
        } else {
            // 继续递归并更新open的值
            return getPersonMessageModel(fromId, toId, open + 1, size,userId);
        }
    }
}
